package com.hyfrogx.modules.app.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.hyfrogx.common.utils.*;
import com.hyfrogx.common.wx.OrderInfo;
import com.hyfrogx.common.wx.OrderReturnInfo;
import com.hyfrogx.common.wx.SignInfo;
import com.hyfrogx.common.wx.Signature;
import com.hyfrogx.modules.app.annotation.Login;
import com.hyfrogx.modules.app.service.WeChatService;
import com.hyfrogx.modules.app.utils.XMLBeanUtils;
import com.thoughtworks.xstream.XStream;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

import static com.hyfrogx.common.utils.Constant.WX_CALLBACK_URL;
import static com.hyfrogx.common.utils.Constant.WX_ORDER_URL;

/**
 * Created by liubin on 2019/1/28
 */
@RestController
@RequestMapping("/app/wx")
@Api(value = "WeChatController", tags = {"微信支付操作相关接口"})
@Slf4j
public class WeChatController {

	@Autowired
	private WeChatService weChatService;

	private static final String WX_APPID = "";
  private static final String WX_MCHID = "";
  private static final String orderId = "123456";


  @Login
  @ApiOperation("调用支付统一下单API")
  @PostMapping("/order")
  public R order(@RequestAttribute("userId") Integer userId, HttpServletRequest request){
    String appIp = IPUtils.getIpAddr(request);
    log.info("小程序发起下单 "+" ip: "+appIp);

    String result = "";

    try {
      OrderInfo order = new OrderInfo();
      order.setAppid(WX_APPID);
      order.setMch_id(WX_MCHID);
      order.setNonce_str(SimpleIdUtils.getUUIDNoLine());
      order.setBody("蛙豆充值");
      order.setOut_trade_no(orderId);
      // 单位为分
      order.setTotal_fee(1);
      order.setSpbill_create_ip(appIp);
      order.setNotify_url(WX_CALLBACK_URL);
      // 小程序固定取值
      order.setTrade_type("JSAPI");
      order.setSign_type("MD5");
      // 生成签名
      order.setSign(Signature.getSign(order));

      log.info("统一下单API请求参数: "+ JSONObject.toJSONString(order));

      result = HttpRequestUtils.sendPost(WX_ORDER_URL, order);

      log.info("统一下单API返回结果: "+result);

      XStream xStream = new XStream();
      xStream.alias("xml", OrderReturnInfo.class);

      OrderReturnInfo returnInfo = (OrderReturnInfo)xStream.fromXML(result);
      JSONObject json = new JSONObject();
      json.put("prepay_id", returnInfo.getPrepay_id());

      result = json.toJSONString();

    } catch (Exception e) {
      e.printStackTrace();
      log.error("-------", e);
    }

    return R.ok().put("data",result);
  }

	/**
	 * 调用再次签名API
	 *
	 * @param userId
	 * @return
	 */
	@Login
	@ApiOperation("调用再次签名API")
	@PostMapping("/sign")
	public R sign(@RequestAttribute("userId") Integer userId, @RequestAttribute("sellerId") Integer sellerId, @RequestParam String repay_id) {
		String result = "";

		// 根据sellerId来获取app_id和app_secret
		String WX_APP_ID = WX_APPID;
//        String WX_APP_SECRET = seller.getAppSecret();

		try {
			SignInfo signInfo = new SignInfo();
			signInfo.setAppId(WX_APP_ID);
			long time = System.currentTimeMillis() / 1000;
			signInfo.setTimeStamp(String.valueOf(time));
			signInfo.setNonceStr(SimpleIdUtils.getUUIDNoLine());
			signInfo.setRepay_id("prepay_id=" + repay_id);
			signInfo.setSignType("MD5");

			JSONObject json = new JSONObject();
			json.put("timeStamp", signInfo.getTimeStamp());
			json.put("nonceStr", signInfo.getNonceStr());
			json.put("package", signInfo.getRepay_id());
			json.put("signType", signInfo.getSignType());
      // 生成签名
			json.put("paySign", Signature.getSign(signInfo));
			log.info("-------再签名: " + json.toJSONString());

			// todo 订单操作 或者app收到后再调用订单支付完成接口

			result = json.toJSONString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.error("------- ", e);
		}

		return R.ok().put("result", result);
	}

  /**
   * 小程序鉴权后调用支付接口API,后台接收微信支付结果通知
   *
   * @param request
   * @return
   */
  @ApiOperation("小程序鉴权后调用支付接口API,后台接收微信支付结果通知")
  @PostMapping("/payResult")
  public String payResult(HttpServletRequest request) {
    log.info("----------------收到微信回调通知");
    String result = "";
    try {
      result = StreamUtils.read(request.getInputStream());
      if (!"".equals(result)) {
        log.info("---------------------微信Api回调：" + result);
        Map<String, String> payResult = XMLBeanUtils.readStringXmlOut(result);
        String result_code = payResult.get("result_code");

        if (StrUtil.equals(result_code, "SUCCESS")) {
          String orderSn = payResult.get("out_trade_no");
          R r = weChatService.payBack(orderId, Constant.PayType.WECHAT.getValue(), payResult.get("time_end"), payResult.get("transaction_id"), BaseWxPayResult.fenToYuan(Convert.toInt(payResult.get("total_fee"))), true);
          if (StrUtil.equals(Convert.toStr(r.get("code")), "0")) {
            return Constant.WX_PAY_NOTIFY_RETURN_XML_OK;
          } else {
            return r.toString();
          }
        } else {
          log.info("---------------------返回代码:" + result_code);
          log.info("---------------------错误描述:" + payResult.get("err_code_des"));
          log.info("---------------------错误代码:" + payResult.get("err_code"));
          return R.error("支付失败").toString();
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    log.info("-----------------result: " + result);
    return R.ok().put("data", result).toString();
  }
}
